﻿using AutoMapper.Internal.Mappers;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;
using WMSSystem.YSL.Dto.CodeRule;
using WMSSystem.YSL.Interfance;

namespace WMSSystem.YSL
{
    /// <summary>
    /// 编码生成器应用服务实现
    /// </summary>
    public class CodeRuleAppService : ApplicationService, ICodeRuleAppService
    {
        private readonly IRepository<CodeRule, Guid> _codeRuleRepository;
        private ILogger<CodeRuleAppService> _logger;

        public CodeRuleAppService(IRepository<CodeRule, Guid> codeRuleRepository, ILogger<CodeRuleAppService> logger)
        {
            _codeRuleRepository = codeRuleRepository;
            _logger = logger;
        }
        /// <summary>
        /// 用于新增编码规则，
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<CodeRuleDto> CreateAsync(CreateOrUpdateCodeRuleDto input)
        {
            var entity = ObjectMapper.Map<CreateOrUpdateCodeRuleDto, CodeRule>(input);
            entity.CurrentNumber = 0;
            entity.LastResetDate = null;
            var result = await _codeRuleRepository.InsertAsync(entity);
            return ObjectMapper.Map<CodeRule, CodeRuleDto>(result);
        }
        /// <summary>
        /// 用于修改编码规则
        /// </summary>
        /// <param name="id"></param>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<CodeRuleDto> UpdateAsync(Guid id, CreateOrUpdateCodeRuleDto input)
        {
            var entity = await _codeRuleRepository.GetAsync(id);
            ObjectMapper.Map(input, entity);
            var result = await _codeRuleRepository.UpdateAsync(entity);
            return ObjectMapper.Map<CodeRule, CodeRuleDto>(result);
        }
        /// <summary>
        /// 用于删除指定ID的编码规则。
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task DeleteAsync(Guid id)
        {
            await _codeRuleRepository.DeleteAsync(id);
        }
        /// <summary>
        /// 获取指定ID的编码规则详情。
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<CodeRuleDto> GetAsync(Guid id)
        {
            var entity = await _codeRuleRepository.GetAsync(id);
            return ObjectMapper.Map<CodeRule, CodeRuleDto>(entity);
        }
        /// <summary>
        /// ：分页获取编码规则列表，
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<PagedResultDto<CodeRuleDto>> GetListAsync(PagedAndSortedResultRequestDto input)
        {
            var query = await _codeRuleRepository.GetQueryableAsync();
            var totalCount = query.Count();
            var items = query.Skip(input.SkipCount).Take(input.MaxResultCount).ToList();
            return new PagedResultDto<CodeRuleDto>(
                totalCount,
                ObjectMapper.Map<List<CodeRule>, List<CodeRuleDto>>(items)
            );
        }
        /// <summary>
        /// 预览下一个编码号，不会自增，适合前端展示。
        /// </summary>
        /// <param name="businessType"></param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public async Task<string> PreviewCodeAsync(string businessType)
        {
            var rule = await _codeRuleRepository.FirstOrDefaultAsync(r => r.BusinessType == businessType);
            if (rule == null)
                throw new Exception($"未找到业务类型为{businessType}的编码规则");

            var now = DateTime.Now;
            var datePart = string.IsNullOrEmpty(rule.DateFormat) ? "" : now.ToString(rule.DateFormat);
            var numberPart = (rule.CurrentNumber + 1).ToString().PadLeft(rule.NumberLength, '0');
            return $"{rule.Prefix}{datePart}{numberPart}";
        }
        /// <summary>
        /// 正式生成编码
        /// </summary>
        /// <param name="businessType"></param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        /*     public async Task<string> GenerateCodeAsync(string businessType)
             {
                 var rule = await _codeRuleRepository.FirstOrDefaultAsync(r => r.BusinessType == businessType);
                 if (rule == null)
                     throw new Exception($"未找到业务类型为{businessType}的编码规则");

                 // 判断是否需要重置流水号
                 var now = DateTime.Now;
                 bool needReset = false;
                 switch (rule.ResetPolicy)
                 {
                     case "Daily":
                         needReset = rule.LastResetDate == null || rule.LastResetDate.Value.Date != now.Date;
                         break;
                     case "Monthly":
                         needReset = rule.LastResetDate == null || rule.LastResetDate.Value.Year != now.Year || rule.LastResetDate.Value.Month != now.Month;
                         break;
                     case "Yearly":
                         needReset = rule.LastResetDate == null || rule.LastResetDate.Value.Year != now.Year;
                         break;
                 }
                 if (needReset)
                 {
                     rule.CurrentNumber = 0;
                     rule.LastResetDate = now;
                 }

                 rule.CurrentNumber++;
                 await _codeRuleRepository.UpdateAsync(rule);

                 var datePart = string.IsNullOrEmpty(rule.DateFormat) ? "" : now.ToString(rule.DateFormat);
                 var numberPart = rule.CurrentNumber.ToString().PadLeft(rule.NumberLength, '0');
                 return $"{rule.Prefix}{datePart}{numberPart}";
             }*/
   
        public async Task<string> GenerateCodeAsync(string businessType)
        {
            try
            {
                var rule = await _codeRuleRepository.FirstOrDefaultAsync(r => r.BusinessType == businessType);
                if (rule == null)
                    throw new Exception($"未找到业务类型为{businessType}的编码规则");

                // 判断是否需要重置流水号
                var now = DateTime.Now;
                bool needReset = false;
                switch (rule.ResetPolicy)
                {
                    case "Daily":
                        needReset = rule.LastResetDate == null || rule.LastResetDate.Value.Date != now.Date;
                        break;
                    case "Monthly":
                        needReset = rule.LastResetDate == null || rule.LastResetDate.Value.Year != now.Year || rule.LastResetDate.Value.Month != now.Month;
                        break;
                    case "Yearly":
                        needReset = rule.LastResetDate == null || rule.LastResetDate.Value.Year != now.Year;
                        break;
                }
                if (needReset)
                {
                    rule.CurrentNumber = 0;
                    rule.LastResetDate = now;
                }

                rule.CurrentNumber++;
                await _codeRuleRepository.UpdateAsync(rule);

                var datePart = string.IsNullOrEmpty(rule.DateFormat) ? "" : now.ToString(rule.DateFormat);
                var numberPart = rule.CurrentNumber.ToString().PadLeft(rule.NumberLength, '0');
                return $"{rule.Prefix}{datePart}{numberPart}";
            }
            catch (Exception ex)
            {
                // 记录日志（假设有 _logger）
                _logger?.LogError(ex, $"生成编码时发生异常，业务类型：{businessType}");
                // 或者用 Console.WriteLine(ex.ToString());

                // 返回友好错误信息，或者抛出自定义异常
                throw new Exception($"生成编码失败，业务类型：{businessType}，错误信息：{ex.Message}", ex);
            }
        }
    }
}
